/**
 * 顶部搜索菜单
 *
 * @date 2019/4/12
 * @update
 *  2019/4/19 兼容中文输入法
 *  2019/4/30 处理网络意外情况造成的无法查询问题
 */
layui.define(['jquery', 'store'], function(exports) {
  var $ = layui.jquery;
  var store = layui.store;

  var MenuSearch = function() {
    this.v = '1.0.0';
    this.cache = {};
    this.data = [];
    this.menus = [];
    this.menuSearchKey = 'searchmenus';
    this.RECENT_MENUS_MAX_VALUE = 10;
  };

  MenuSearch.prototype.render = function(target, data) {
    var $target = $(target);

    if (!$target[0]) return this;
    $target.attr('autocomplete', 'off');

    this.data = data;
    this.cache.$el = $target;
    this.mount();
    this.event();
  };

  MenuSearch.prototype.mount = function() {
    var data = this.data;
    var $el = this.cache.$el;
    var $ms = $('<div class="layadmin-menusearch layui-anim layui-anim-upbit"></div>');
    var $msBody = $([
      '<div class="layadmin-menusearch-body">',
      (function() {
        var placeholder = $el.attr('placeholder');
        var html = '<div class="layadmin-menusearch-item layadmin-menusearch-tip layadmin-this">' + (placeholder || '搜索') + '</div>';
        $.each(data, function() {
          html +=
            '<div class="layadmin-menusearch-item" data-id="' + this.id + '" lay-href="' + this.url + '" title="' + this.title + '">' +
            ' <cite class="layadmin-menusearch-item--title">' + this.name + '</cite>' +
            ' <div class="layadmin-menusearch-item--detail">' + (this.title ? this.title.replace(/\>\>/gi, ' / ') : '') + '</div>' +
            '</div>';
        });
        return html;
      }()),
      '</div>'
    ].join(''));
    // var $msFooter = $([
    //   '<div class="layui-card layadmin-menusearch-footer">',
    //   ' <div class="layui-card-header">最近搜索<a class="layadmin-menusearch-btn layadmin-menusearch-clear">清空</a></div>',
    //   ' <div class="layui-card-body">',
    //   this.mountFooter(),
    //   ' </div>',
    //   '</div>'
    // ].join(''))

    $ms.append($msBody);
    // .append($msFooter)
    $el.after($ms);

    this.cache.$ms = $ms;
    this.cache.$msBody = $msBody;
    this.cache.$msFooter = {};

    return $ms;
  };

  MenuSearch.prototype.mountFooter = function() {
    var BadgeClassNames = [
      'layui-badge',
      'layui-badge layui-bg-orange',
      'layui-badge layui-bg-green',
      'layui-badge layui-bg-cyan',
      'layui-badge layui-bg-blue',
      'layui-badge layui-bg-black',
      'layui-badge layui-bg-gray',
      'layui-badge-rim'
    ];

    var menus = store.get(this.menuSearchKey);
    this.menus = $.isArray(menus) ? menus : [];

    var html = ''; var index = Math.random() * BadgeClassNames.length | 0;
    var i = this.menus.length - 1;

    if (i < 0) {
      html += '<div class="layadmin-menusearch-nodata">无搜素记录</div>';
    } else {
      while (i >= 0) {
        html +=
          '<div class="' + BadgeClassNames[index] + ' layadmin-menusearch-btn">' +
          ' <span>' + this.menus[i] + '</span>' +
          ' <i class="layui-icon layui-icon-close"></i>' +
          '</div>';
        i--;
      }
    }

    return html;
  };

  MenuSearch.prototype.event = function() {
    var _this = this;
    var _cache = _this.cache;
    var $el = _cache.$el;
    var $ms = _cache.$ms;
    var $msBody = _cache.$msBody;
    var $msFooter = _cache.$msFooter;
    var $msItems = $msBody.find('.layadmin-menusearch-item');

    var SHOW = 'layui-show';
    var HIDE = 'layui-hide';
    var THIS = 'layadmin-this';
    var DISABLED = 'layui-disabled';
    var NONE = 'layadmin-menusearch-nodata';
    var KEYS = { TAB: 9, ENTER: 13, ESC: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40 };

    var initValue = ''; var thatInput; var nearElem;

    var isOnComposition = false; var isFocus = false;

    var handleMatch = function($item, value) {
      var $itemTitle = $item.find('.layadmin-menusearch-item--title');
      var $itemDetail = $item.find('.layadmin-menusearch-item--detail');
      var tempTitle = $itemTitle.text().replace(/<\/?strong>/g, '');
      var tempDetail = $itemDetail.text().replace(/<\/?strong>/g, '');

      if (value) {
        var formatTitle = tempTitle.replace(new RegExp('(' + value + ')', 'gi'), '<strong>$1<\/strong>');
        var formatDetail = tempDetail.replace(new RegExp('(' + value + ')', 'gi'), '<strong>$1<\/strong>');
        $itemTitle.html(formatTitle);
        $itemDetail.html(formatDetail);
      } else {
        $itemTitle.html(tempTitle);
        $itemDetail.html(tempDetail);
      }
    };

    var hide = function(e, clear) {
      if (!$(e.target).parent().hasClass('layui-nav-item') || clear) {
        $ms.removeClass(SHOW);
        isFocus = false;
        isOnComposition = false;
        $msItems.each(function() {
          handleMatch($(this));
        });
        thatInput && initValue && thatInput.val(initValue);
      }
      thatInput = null;
    };

    var followScroll = function() {
      var $thisItem = $msBody.children('.layadmin-menusearch-item.' + THIS);

      if (!$thisItem[0]) return;

      var posTop = $thisItem.position().top;
      var bodyHeight = $ms.height();
      var itemHeight = $thisItem.outerHeight();

      // 若选中元素在滚动条不可见底部
      if (posTop > bodyHeight) {
        $ms.scrollTop(posTop + $ms.scrollTop() - bodyHeight + itemHeight - 5);
      }

      // 若选择元素在滚动条不可见顶部
      if (posTop < 0) {
        $ms.scrollTop(posTop + $ms.scrollTop() - 5);
      }
    };

    var notOption = function(value, cb, origin) {
      var matchNum = 0;

      $msItems.each(function() {
        var $item = $(this);
        var itemValue = $item.text().replace(/\s|>/g, '');

        handleMatch($item, value);
        var notMatch = itemValue.indexOf(value) === -1;
        if (value === '' || (origin === 'blur') ? value !== itemValue : notMatch) matchNum++;
        origin === 'keyup' && $item[notMatch ? 'addClass' : 'removeClass'](HIDE);
      });

      var isNone = matchNum === $msItems.length;
      cb(isNone);
      return isNone;
    };

    var showDown = function() {
      $ms.addClass(SHOW);
      $msItems.removeClass(HIDE);
      $msItems.eq(0).addClass(THIS).siblings().removeClass(THIS);
      nearElem = null;
      followScroll();
    };

    var hideDown = function(choose) {
      isFocus = false;
      isOnComposition = false;
      $ms.removeClass(SHOW);
      $msItems.each(function() {
        handleMatch($(this));
      });
      $el.blur();
      nearElem = null;
      if (choose) return;
      notOption($el.val(), function(none) {
        if (none) {
          initValue = $msItems.first().html();

          if (initValue === $el.attr('placeholder')) {
            initValue = '';
          }
          $el.val(initValue || '');
        }
      });
    };

    // $el.on('click', function(e) {
    //   if ($ms.hasClass(SHOW)) {
    //     hideDown()
    //   } else {
    //     hide(e, true)
    //     showDown()
    //   }
    //   $msBody.find('.' + NONE).remove()
    // })

    $el.on('focus', function(e) {
      if (!isFocus) {
        hide(e, true);
        showDown();
        isFocus = true;
      } else {
        isFocus = false;
      }
    });

    $el.on('compositionstart compositionupdate compositionend', function(event) {
      if (event.type === 'compositionend') {
        isOnComposition = false;
        $el.trigger('input');
      } else {
        isOnComposition = true;
      }
    });

    $el.on('input', function(e) {
      if (isOnComposition) return;
      var value = e.target.value;

      notOption(value, function(none) {
        if (none) {
          $msBody.find('.' + NONE)[0] || $msBody.append('<div class="' + NONE + '" style="line-height: 40px">无匹配项</div>');
        } else {
          $msBody.find('.' + NONE).remove();
        }
      }, 'keyup');

      if (value === '') {
        $msBody.find('.' + NONE).remove();
      }

      followScroll();
    });

    $el.on('keydown', function(e) {
      var keyCode = e.keyCode || e.which;

      var setThis = function(prevNext, thisElem1) {
        var nearDd, cacheNearElem;
        e.preventDefault();

        // 得到当前队列元素
        var thisElem = (function() {
          var thisItem = $msBody.children('.layadmin-menusearch-item.' + THIS);

          if ($msBody.children('.layadmin-menusearch-item.' + HIDE)[0] && prevNext === 'next') {
            var showItem = $msBody.children('.layadmin-menusearch-item:not(.' + HIDE + ')');
            var firstIndex = showItem.eq(0).index();

            if (firstIndex >= 0 && firstIndex < thisItem.index() && !showItem.hasClass(THIS)) {
              return showItem.eq(0).prev()[0] ? showItem.eq(0).prev() : $msBody.children(':last');
            }
          }

          if (thisElem1 && thisElem1[0]) {
            return thisElem1;
          }

          if (nearElem && nearElem[0]) {
            return nearElem;
          }

          return thisItem;
        }());

        cacheNearElem = thisElem[prevNext](); // 当前元素的附近元素
        nearDd = thisElem[prevNext]('.layadmin-menusearch-item:not(.' + HIDE + ')'); // 当前可视元素的 dd 元素

        // 如果附近的元素不存在，则停止执行，并清空 nearElem
        if (!cacheNearElem[0]) return nearElem = null;

        // 记录附近的元素，让其成为下一个当前元素
        nearElem = thisElem[prevNext]();

        // 如果附近不是 dd ，或者附近的 dd 元素是禁用状态，则进入递归查找
        if ((!nearDd[0] || nearDd.hasClass(DISABLED)) && nearElem[0]) {
          return setThis(prevNext, nearElem);
        }

        nearDd.addClass(THIS).siblings().removeClass(THIS); // 标注样式

        followScroll();
      };

      if (keyCode === KEYS.UP) {
        e.stopPropagation();
        e.preventDefault();
        setThis('prev');
      }

      if (keyCode === KEYS.DOWN) {
        e.stopPropagation();
        e.preventDefault();
        setThis('next');
      }

      if (keyCode === KEYS.ENTER) {
        e.preventDefault();
        $msBody.children('.layadmin-menusearch-item.' + THIS).trigger('click');
      }

      if (keyCode === KEYS.TAB) {
        hideDown();
      }

      if (keyCode === KEYS.ESC) {
        e.stopPropagation();
        e.preventDefault();
        hideDown();
      }
    });

    $el.on('keyup', function(e) {
      var keyCode = e.keyCode || e.which;

      if (keyCode === KEYS.TAB ||
        keyCode === KEYS.ENTER ||
        keyCode === KEYS.LEFT ||
        keyCode === KEYS.UP ||
        keyCode === KEYS.RIGHT ||
        keyCode === KEYS.DOWN) {
        return false;
      }
    });

    $el.on('blur', function(e) {
      thatInput = $el;
      initValue = $msItems.first().html(); // 重新获得初始选中值

      // 如果是第一项，且文本值等于 placeholder，则清空初始值
      if (initValue === $el.attr('placeholder')) {
        initValue = '';
      }

      setTimeout(function() {
        notOption($el.val(), function(none) {
          initValue || $el.val(''); // none && !initValue
        }, 'blur');
      }, 200);
    });

    $msBody.on('click.ms', '.layadmin-menusearch-item', function() {
      var value = $el.val();
      // var menus = _this.menus
      //
      // menus.push(value)
      // if (menus.length > _this.RECENT_MENUS_MAX_VALUE) {
      //   menus.splice(0, menus.length -  _this.RECENT_MENUS_MAX_VALUE) // 删除旧的记录
      // }
      // store.set(_this.menuSearchKey, menus)
      $msItems.removeClass(THIS);
      $(this).addClass(THIS);
      hideDown();
    });

    // $msFooter.on('click.ms', '.layadmin-menusearch-btn', function() {
    //   var $this = $(this)
    //   if ($this.hasClass('layadmin-menusearch-clear')) {
    //     store.del(_this.menuSearchKey)
    //     _this.menus = []
    //   } else {
    //     $el.val($this.find('span').text())
    //   }
    // })
    //
    // $msFooter.on('click.ms', '.layui-icon-close', function(e) {
    //   $(this).parent().remove()
    //   layui.stope(e)
    // })

    $(document).off('click', hide).on('click', hide); // 点击其它元素关闭 select
  };

  exports('menusearch', new MenuSearch());
});
